/*
 * 
 */
package ch.gje.playios.communication;

import ch.gje.playios.server.HTTPConnection;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Represents a client connected over WebSocket
 *
 * @author jannis <jannis@gje.ch>
 */
public abstract class WebSocketClient {

    /**
     * The paired partner
     */
    protected WebSocketClient partner;
    /**
     * The connection to the client
     */
    private HTTPConnection connection;

    /**
     * Constructor
     *
     * @param connection the HTTP connection
     */
    public WebSocketClient(HTTPConnection connection) {
        this.connection = connection;
    }

    /**
     * Sets the partner
     * @param partner the partner client
     */
    public void pairWith(WebSocketClient partner) {
        if (this.partner == null && partner.partner == null) {
            this.partner = partner;
            partner.partner = this;
            onPaired();
            partner.onPaired();
        } else {
            throw new ClientAlreadyPairedException();
        }
    }

    /**
     * Unpairs this client
     */
    public void unpair() {
        if (this.partner != null) {
            this.partner = null;
            onUnpaired();
        }
    }

    /**
     * Sends a message to this client as a WebSocket frame
     * @param message the message
     */
    public void send(String message) {
        try {
            connection.sendWebSocketFrame(message);
        } catch (IOException ex) {
            Logger.getLogger(WebSocketClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Sends a command to the client ("play-ios protocoll")
     * @param command the command
     */
    public void sendCommand(String command) {
        send('/' + command);
    }

    /**
     * Sends a command with a value to the client ("play-ios protocoll")
     * @param command the command
     * @param value the value
     */
    public void sendCommand(String command, Object value) {
        sendCommand(command + ':' + value);
    }

    /**
     * Handles closing of the WebSocket connection
     */
    public void onClose() {
        if (partner != null) {
            partner.unpair();
        }
        this.unpair();
    }

    /**
     * Handles successful pairing
     */
    public abstract void onPaired();

    /**
     * Handles unpairing
     */
    public abstract void onUnpaired();

    /**
     * Handles message receiving
     * @param message the received message
     */
    public abstract void onReceive(String message);
}
